Skip to content

Make TestMailer proxying #117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 3 commits into from
Closed

Conversation

mikk150
Copy link

@mikk150 mikk150 commented Feb 7, 2025

I would like to test my application, that totally rewrites email sending logic, and found yiisoft/yii2#14718 having same issue

this should make so that codeception proxies applications email client, so that you could use any yii2 emailing client so long as it's message extends yii\mail\BaseMessage

@SamMousa
Copy link
Collaborator

SamMousa commented Feb 7, 2025

I like this idea for sure!
In this case won't the Mailer need to be configured or it will throw errors?

How about supporting a null Mailer instead so by default it doesn't proxy but it can be configured to proxy.
Note btw that all instanceof checks that you might do in user code will still fail.

@mikk150
Copy link
Author

mikk150 commented Feb 7, 2025

I like this idea for sure! In this case won't the Mailer need to be configured or it will throw errors?

No, there is default configuration for mailer defined for this case, and it should be compatible with current codeception modules mailer

How about supporting a null Mailer instead so by default it doesn't proxy but it can be configured to proxy.

I do not see why would we want to over complicate it when current implementation just acts as inferior version of symphony mailer

Note btw that all instanceof checks that you might do in user code will still fail.

Nothing that can be done unfortunately

edit://
other way to do it would involve mocking....

@SamMousa
Copy link
Collaborator

SamMousa commented Feb 7, 2025

No, there is default configuration for mailer defined for this case, and it should be compatible with current codeception modules mailer

You just set it to the default mailer class right? But that will throw exceptions: https://github.com/yiisoft/yii2-symfonymailer/blob/master/src/Mailer.php#L76

    private function getTransport(): TransportInterface
    {
        /** @psalm-suppress RedundantPropertyInitializationCheck Yii2 configuration flow does not guarantee full initialisation */
        if (!isset($this->_transport)) {
            throw new InvalidConfigException('No transport was configured.');
        }
        return $this->_transport;
    }

I think in the default config you supply you should configure the transport (Symfony includes a NullTransport that you can use). If you don't do it your fix will break stuff for others.

(This is what I think based on reading the code; you may argue this point if you know it works differently)

Nothing that can be done unfortunately

I was thinking the new lazy proxies (in php8.4) might be of use here; but I don't think you can actually intercept calls.

other way to do it would involve mocking....

Nah that's definitely overly complicated.

Co-authored-by: Sam Mousa <github@sam.mousa.nl>
@SamMousa
Copy link
Collaborator

LGTM; some basics that tests / phpstan are pointing out.

If you can please add return types as well. This lib requires php >= 8.0 meaning we can add things like :void return type even if the base classes in Yii don't have them. -- i will not block merging for this, so it's up to you.

@mikk150
Copy link
Author

mikk150 commented Feb 10, 2025

LGTM; some basics that tests / phpstan are pointing out.

If you can please add return types as well. This lib requires php >= 8.0 meaning we can add things like :void return type even if the base classes in Yii don't have them. -- i will not block merging for this, so it's up to you.

I'm going to just add basic docker-compose in order to run tests(as I work exclusively in containers nowadays in order to not think about what version of PHP or other dependencies some particular project needs), if that is fine with this project

We cannot blanket add `$transport` field to Mailer, as not all implementations may have it
add basic docker-compose file that helps run tests and phpstan
@Eseperio
Copy link

I´ve just came into the issue mentioned here a few days ago and the solution i used is very simple. Using container definitions you can easiliy override TestMailer and with a simple and harmless code implementation in your mailer you can make it complete compatible with codeception yii2 module: yiisoft/yii2#14718

@SamMousa
Copy link
Collaborator

It's not a clean solution though... If internal structure of codeception changes your tests will break.

@SamMousa
Copy link
Collaborator

I'm sorry but these last changes add all kinds of implementation specific knowledge. I don't see why codeception needs to know about swiftmailer or symfony mailer...

@SamMousa
Copy link
Collaborator

I realize I contradict my earlier statement, I did not realize we'd have to add an additional dependency.

@@ -29,7 +29,8 @@
"codemix/yii2-localeurls": "^1.7",
"codeception/module-asserts": ">= 3.0",
"codeception/module-filesystem": "> 3.0",
"phpstan/phpstan": "^1.10"
"phpstan/phpstan": "^1.10",
"yiisoft/yii2-swiftmailer": "^2.0.0"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect. Why are we adding swiftmailer?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right.. it isn't needed, but phpstan was failing otherwise

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because I think that if we worry about symfonymailer we should worry about swiftmailer
and symfonymailer comes from dependecy to yiisoft/yii2-app-advanced

I actually still do not think that we need to set NullTransports to them, because again, TestMailer class overwrites TestMailer::sendMessage() not to send, so it should fail only if MessageInterface::send() does the sending itself, but then no amount of NullTransports fix it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants